#include "cybertron/sensor/noise/LinearTimeNoise.hpp"

CYBERTRON_BEGIN

LinearTimeNoise::LinearTimeNoise(float weight/* = 1e7*/)
	: TimeNoise(ELinearTimeNoise)
{
	std::uniform_real_distribution<float> distribution(0.6f, 1.0f);
	m_initWeight = vec3(distribution(randomEngine()) / weight, distribution(randomEngine()) / weight, distribution(randomEngine()) / weight);
	m_weight = m_initWeight;
	m_bias = vec3(0.0f);
}

LinearTimeNoise::LinearTimeNoise(float horizontalWeight, float verticalWeight)
	: TimeNoise(ELinearTimeNoise)
{
	std::uniform_real_distribution<float> distribution(0.6f, 1.0f);
	m_initWeight = vec3(distribution(randomEngine()) / horizontalWeight, distribution(randomEngine()) / horizontalWeight, distribution(randomEngine()) / verticalWeight);
	m_weight = m_initWeight;
	m_bias = vec3(0.0f);
}

LinearTimeNoise::LinearTimeNoise(const vec3& weight)
	: TimeNoise(ELinearTimeNoise)
{
	m_initWeight = 1.0f / weight;
	m_weight = m_initWeight;
	m_bias = vec3(0.0f);
}

LinearTimeNoise::~LinearTimeNoise()
{
}

vec3 LinearTimeNoise::update() {
	float seconds = (float)elapsedTime();
	m_value = m_weight * seconds + m_bias;
	return m_value;
}

void LinearTimeNoise::drift(float rotation)
{
	// drift some random offset from rotation.
	vec3 deltaWeight = vec3(rotation / 2, rotation / 2, 0);
	float seconds = (float)elapsedTime();
	m_bias += -deltaWeight * seconds;
	m_weight += deltaWeight;
}

void LinearTimeNoise::resetNoise()
{
	m_weight = m_initWeight;
	m_bias = vec3(0.0f);
	TimeNoise::resetNoise();
}

CYBERTRON_END